通过我之前的RestTemplate简单分析可以知道,虽然spring cloud 之中定义了LoadBalancerClient作为负载均衡的通用接口,并且对于Ribbon有了具体的实现RibbonLoadBalancerClient,但是,在具体使用客户端负载均衡时是使用Ribbon的ILoadBalancer接口实现的,现在我就根据ILoadBalancer接口的实现类来具体的分析分析。
AbstractLoadBalancer
AbstractLoadBalancer是ILoadBalancer的抽象实现,定义了关于服务器分组的枚举类ServerGroup,三种不同类型
public enum ServerGroup{
ALL,//所有服务实例
STATUS_UP,//正常服务的实例
STATUS_NOT_UP//停止服务的实例
}
还有一个chooseServer()方法,即调用接口的chooseServer(Object key)方法,表示在选择服务实例的时候忽略key条件判断。除此之外,还定义了两个抽象函数
- List<Server> getServerList(ServerGroup serverGroup):根据服务分组获取对应的服务实例列表
- LoadBalancerStats getLoadBalancerStats():定义了获取LoadBalancerStats的方法
下面,贴出具体源码
public abstract class AbstractLoadBalancer implements ILoadBalancer {
public enum ServerGroup{
ALL,
STATUS_UP,
STATUS_NOT_UP
}
public Server chooseServer() {
return chooseServer(null);
}
public abstract List<Server> getServerList(ServerGroup serverGroup);
public abstract LoadBalancerStats getLoadBalancerStats();
}
具体的类结构
首先看 BaseLoadBalancer
BaseLoadBalancer是Ribbon负载均衡的基础实现类,定义了很多的基础概念
- addServers(List<Server> newServers) 实现,向负载均衡中增加新的 服务实例列表;将所有的服务实例假如到newServers中,然后调用setServersList方法对newList处理,负载均衡的扩展类一般都是通过对setServersList方法重写来实现的
public void addServers(List<Server> newServers) { if (newServers != null && newServers.size() > 0) { try { ArrayList<Server> newList = new ArrayList<Server>(); newList.addAll(allServerList); newList.addAll(newServers); setServersList(newList); } catch (Exception e) { logger.error("LoadBalancer [{}]: Exception while adding Servers", name, e); } } }
- markServerDown(Server server):标记服务处于暂停状态
public void markServerDown(Server server) { if (server == null || !server.isAlive()) { return; } logger.error("LoadBalancer [{}]: markServerDown called on [{}]", name, server.getId()); server.setAlive(false); // forceQuickPing(); notifyServerStatusChangeListener(singleton(server)); }
- getReachableServers():获取可用的服务列表
public List<Server> getReachableServers() { return Collections.unmodifiableList(upServerList); }
- List<Server> getAllServers():获取所有服务列表
public List<Server> getAllServers() { return Collections.unmodifiableList(allServerList); }
- 两个维护服务实例server对象的列表,一个用于存储所有服务实例的清单,另一个用于存储正常服务的实例清单
@Monitor(name = PREFIX + "AllServerList", type = DataSourceType.INFORMATIONAL) protected volatile List<Server> allServerList = Collections .synchronizedList(new ArrayList<Server>()); @Monitor(name = PREFIX + "UpServerList", type = DataSourceType.INFORMATIONAL) protected volatile List<Server> upServerList = Collections .synchronizedList(new ArrayList<Server>());
-
定义了心跳检测的IPing对象,默认为null,在构造方法里传入
protected IPing ping = null;
-
定义了心跳检测的执行策略对象IPingStrategy,默认使用的是SerialPingStrategy,该策略使用的是线性遍历ping服务实例的方式检测。当IPing的速度慢,或是Server列表过大的时候,就会影响性能了。
private static class SerialPingStrategy implements IPingStrategy { @Override public boolean[] pingServers(IPing ping, Server[] servers) { int numCandidates = servers.length; boolean[] results = new boolean[numCandidates];